/*
先弄清楚数据双向绑定：
Observer：监听器，用来劫持并监听所有属性。只创建一个。如果属性有变动，就通知订阅者。
Watcher：订阅者。自定义订阅者，有多个。收到属性变化的通知并执行相应函数，从而更新视图。
Dep：消息订阅器，手机订阅者。当Observer监听到属性有变化时，不直接通知订阅者，而是通过Dep来通知订阅者。所以Observer是和Dep有关的
*/

function Compile(el, vm) {
    vm.$el = document.querySelector(el);
    let fragment = document.createDocumentFragment();
    let child = el.firstChild;
    while (child) {
        fragment.appendChild(child);
        child = el.firstChild;
    }

    // 定义方法
    if (typeof Compile._initialized == "undefined") {
        Compile.prototype.compileAll = function(fragment) {
            let self = this;
            const patternReg = /\{\{(.*)\}\}/;
            // 因为[].slice中，[].slice()没有加括号，相当于未调用slice方法
            // 这时[].slice返回值是slice这个函数，所以可以调用call方法
            // 相当于fragment.childNodes调用slice方法，因为未传进任何参数，所以原值返回
            [].slice.call(fragment.childNodes).forEach(node => {
                let text = node.textContent;
                if (self.isTextNode && patternReg.test(text)) {
                    node.textContent = text.replace(patternReg, vm[key]);

                }


                if (node.childNodes && node.childNodes.length) {
                    self.compileAll(node);
                }
            });
        };

        Compile.prototype.compileText = function(node, key) {

        };


        // 判断不同的指令和模板
        Compile.prototype.isTextNode = function(node) {
            return node.nodeType == 3;
        };
        Compile.prototype.isElementNode = function(node) {
            return node.nodeType == 1;
        };
        Compile.prototype.isDirective = function(attr) {
            return attr.indexOf('v-') == 0;
        };
        Compile.prototype.isEventDirective = function(dir) {
            return dir.indexOf('on:') === 0;
        };


        Compile._initialized = true;
    }
}

function Observer(data) {
    for (const key in data) {
        let val = data[key];
        Object.defineProperty(data, key, {
           enumerable: true,
            get() {
               return val;
            },
            set(newVal) {
               if (newVal === val) {
                   return;
               }
               val = newVal;
            }
        });
    }
}

function Dep() {
    //----定义属性
    this.subscribers = [];


    //----定义方法
    if(typeof Dep._initialized == "undefined") {
        // 添加订阅者
        Dep.prototype.addSubscriber = function(subscriber) {
           this.subscribers.push(subscriber);
        };

        // 通知Watcher更新
        Dep.prototype.notify = function() {
            this.subscribers.forEach(function (subscriber) {

            });
        };

        Dep._initialized = true;
    }
}

function Watcher(vm, key, fun) {
    //----定义属性
    this.vm = vm;
    this.key = key;
    this.fun = fun;


    //----定义方法
    if(typeof Watcher._initialized == "undefined") {
        Watcher.prototype.update = function() {
            this.fun(this.vm[this.key]);
        };

        Watcher._initialized = true;
    }
}